using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;

using SBPweb.Themes.Windows;
using SBPweb.Themes.Windows.Skins;

namespace SBPweb.Controls.Windows.Tab
{
	/// <summary>
	/// Class of TabPage
	/// </summary>
	[ToolboxBitmap(typeof(System.Windows.Forms.TabPage))]
	public partial class TabPage : System.Windows.Forms.TabPage, ISkinnable
	{
		#region Private members

		private bool mUseDefaultSkin;
		private Margin mSizingMargin;
		private Margin mContentMargin;
		private Skin mSkin;

		#endregion

		#region Constructor logic

		/// <summary>
		/// Constructor of TabPage
		/// </summary>
		public TabPage()
		{
			SetStyle();
			InitializeSkin();
			InitializeComponent();
			RegisterEventHandlers();
		}

		/// <summary>
		/// Constructor of TabPage
		/// </summary>
		/// <param name="skin">skin</param>
		public TabPage(Skin skin)
		{
			mSkin = skin;
			
			SetStyle();
			InitializeSkin();
			InitializeComponent();
			RegisterEventHandlers();
		}

		private void SetStyle()
		{
			if (Skin != null)
			{
				base.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
			}
			else
			{
				base.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor, true);
			}
		}

		private void RegisterEventHandlers()
		{
			DefaultLookAndFeel.OnSkinChanged += new EventHandler(DefaultLookAndFeel_OnSkinChanged);
		}

		private void InitializeSkin()
		{
			if (Skin == null)
			{
				this.mContentMargin = new Margin();
				this.mSizingMargin = new Margin();
			}
			else
			{
				this.mContentMargin = Skin.CachedProperties.TabPaneContentMargin;
				this.Margin = this.mContentMargin.Padding;
				this.mSizingMargin = Skin.CachedProperties.TabPaneSizingMargin;
			}
		}

		#endregion

		#region Custom draw

		/// <summary>
		/// On paint
		/// </summary>
		/// <param name="e">event args</param>
		protected override void OnPaint(PaintEventArgs e)
		{
			if (Skin == null)
			{
				base.OnPaint(e);
				return;
			}

			System.Drawing.Image img = Skin.CachedProperties.TabPaneImage;
			bool verticalLayout = Skin.CachedProperties.TabPaneLayout == LayoutDirection.Vertical;

			int imgWidth = img.Width;
			int imgHeight = img.Height;
			int imgTop = 0;
			int imgLeft = 0;

			#region Image parts
			Rectangle iLT = new Rectangle(imgLeft, imgTop, mSizingMargin.Left, mSizingMargin.Top);
			Rectangle iT = new Rectangle(imgLeft + mSizingMargin.Left, imgTop, imgWidth - mSizingMargin.Horizontal, mSizingMargin.Top);
			Rectangle iRT = new Rectangle(imgLeft + imgWidth - mSizingMargin.Right, imgTop, mSizingMargin.Right, mSizingMargin.Top);
			Rectangle iLM = new Rectangle(imgLeft, imgTop + mSizingMargin.Top, mSizingMargin.Left, (imgHeight - 1) - mSizingMargin.Vertical);
			Rectangle iM = new Rectangle(imgLeft + mSizingMargin.Left, imgTop + mSizingMargin.Top, imgWidth - mSizingMargin.Horizontal, (imgHeight - 1) - mSizingMargin.Vertical);
			Rectangle iRM = new Rectangle(imgLeft + imgWidth - mSizingMargin.Right, imgTop + mSizingMargin.Top, mSizingMargin.Right, (imgHeight - 1) - mSizingMargin.Vertical);
			Rectangle iLB = new Rectangle(imgLeft, imgTop + imgHeight - mSizingMargin.Bottom, mSizingMargin.Left, mSizingMargin.Bottom);
			Rectangle iB = new Rectangle(imgLeft + mSizingMargin.Left, imgTop + imgHeight - mSizingMargin.Bottom, imgWidth - mSizingMargin.Horizontal, mSizingMargin.Bottom);
			Rectangle iRB = new Rectangle(imgLeft + imgWidth - mSizingMargin.Right, imgTop + imgHeight - mSizingMargin.Bottom, mSizingMargin.Right, mSizingMargin.Bottom);
			#endregion

			#region Window parts
			Rectangle tLT = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Top, mSizingMargin.Left, mSizingMargin.Top);
			Rectangle tT = new Rectangle(this.ClientRectangle.Left + mSizingMargin.Left, this.ClientRectangle.Top, this.ClientRectangle.Width - mSizingMargin.Horizontal, mSizingMargin.Top);
			Rectangle tRT = new Rectangle(this.ClientRectangle.Right - mSizingMargin.Right, this.ClientRectangle.Top, mSizingMargin.Right, mSizingMargin.Top);
			Rectangle tLM = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Top + mSizingMargin.Top, mSizingMargin.Left, this.ClientRectangle.Height - mSizingMargin.Vertical);
			Rectangle tM = new Rectangle(this.ClientRectangle.Left + mSizingMargin.Left, this.ClientRectangle.Top + mSizingMargin.Top, this.ClientRectangle.Width - mSizingMargin.Horizontal, this.ClientRectangle.Height - mSizingMargin.Vertical);
			Rectangle tRM = new Rectangle(this.ClientRectangle.Right - mSizingMargin.Right, this.ClientRectangle.Top + mSizingMargin.Top, mSizingMargin.Right, this.ClientRectangle.Height - mSizingMargin.Vertical);
			Rectangle tLB = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Bottom - mSizingMargin.Bottom, mSizingMargin.Left, mSizingMargin.Bottom);
			Rectangle tB = new Rectangle(this.ClientRectangle.Left + mSizingMargin.Left, this.ClientRectangle.Bottom - mSizingMargin.Bottom, this.ClientRectangle.Width - mSizingMargin.Horizontal, mSizingMargin.Bottom);
			Rectangle tRB = new Rectangle(this.ClientRectangle.Right - mSizingMargin.Right, this.ClientRectangle.Bottom - mSizingMargin.Bottom, mSizingMargin.Right, mSizingMargin.Bottom);
			#endregion

			#region Drawing
			e.Graphics.DrawImage(img, tLT, iLT, GraphicsUnit.Pixel);
			e.Graphics.DrawImage(img, tT, iT, GraphicsUnit.Pixel);
			e.Graphics.DrawImage(img, tRT, iRT, GraphicsUnit.Pixel);
			e.Graphics.DrawImage(img, tLM, iLM, GraphicsUnit.Pixel);
			e.Graphics.DrawImage(img, tM, iM, GraphicsUnit.Pixel);
			e.Graphics.DrawImage(img, tRM, iRM, GraphicsUnit.Pixel);
			e.Graphics.DrawImage(img, tLB, iLB, GraphicsUnit.Pixel);
			e.Graphics.DrawImage(img, tB, iB, GraphicsUnit.Pixel);
			e.Graphics.DrawImage(img, tRB, iRB, GraphicsUnit.Pixel);
			#endregion
		}

		#endregion

		#region Events

		private void DefaultLookAndFeel_OnSkinChanged(object sender, EventArgs e)
		{
			InitializeSkin();
			Invalidate(true);
		}

		#endregion

		#region ISkinnable Members

		/// <summary>
		/// Use default skin?
		/// </summary>
		[Category("Look && feel")]
		public bool UseDefaultSkin
		{
			get
			{
				return mUseDefaultSkin;
			}
			set
			{
				mUseDefaultSkin = value;
				Invalidate();
			}
		}

		/// <summary>
		/// Used skin
		/// </summary>
		[Category("Look && feel")]
		public Skin Skin
		{
			get
			{
				if (this.UseDefaultSkin)
				{
					return DefaultLookAndFeel.Skin;
				}

				return mSkin;
			}
			set
			{
				mSkin = value;
				Invalidate();
			}
		}

		#endregion
	}
}
